#include "Lily_help.h"
#include <math.h>
#include "hashlib.h"

int32_t search_cmd_in_Lily_ui(const char *item)
{
	return search_obj(lily_ui.cmds, item);
}
int32_t public_a_cmd_link(const char *name, Cmdline_def link)
{
	return public_a_cmd_link_doc(name, link, "none");
}
int32_t public_a_cmd_link_doc(const char *name, Cmdline_def link, const char*help_doc)
{
	Cmd_t cmd;
	cmd.name = (char *)name;
	cmd.annotation = help_doc;
	cmd.todo = link;
	return public_obj(lily_ui.cmds, &cmd);
}
int32_t remove_cmd(int32_t index)
{
	return list_remove_at(lily_ui.cmds, index);
}
int32_t remove_cmd_by_str(char *cmd)
{
	int32_t index = search_cmd_in_Lily_ui(cmd);
	if (index < 0)
		return -1;
	return remove_cmd(index);
}

int32_t shell_do_cmd(char* rx)
{
	int32_t hit = 0;
	int32_t return_code;
	char tx[TX_len];
	Li_List list = str_cmd_split(rx);
	if (!list)
	{
		return 0;
	}
	if (list->count == 0)
	{
		delete_list(list);
		return 0;
	}
	char** tokens = list_content(list, char*);

	hit = search_cmd_in_Lily_ui(tokens[0]);
	if (hit < 0)
	{
		delete_list(list);
		return 0; 
	}

	Cmd_t* cmd = (Cmd_t*)list_index(lily_ui.cmds, hit);
	str* para = (char**)(list->content);
	hit = list->count;
	char* tx1 = tx;
	int32_t i;
	for (i = 0; i < hit; i++)
	{
		if (para[i][0] != '$')
			continue;
		int32_t index = search_var_in_Lily_ui(para[i] + 1);
		if (index < 0)
		{
			delete_list(list);
			li_error("\'$\' used, field not exists", -__LINE__);
		}
		int32_t at = _ebrace_value_from_string(para[i]);
		if (at == -1)
			at = 0;
		if (at < 0) 
		{
			delete_list(list);
			__li_error_msg = "[]index error";
			return -3; // index out
		}
		if (!at && (li_vars + index)->type == 's')
		{
			para[i] = (li_vars + index)->val.vs;
		}
		else
		{
			_var_to_string(tx1, li_vars + index, at);
			para[i] = tx1; 
			tx1 += strlen(tx1) + 1;
			if (tx1 >= tx + TX_len)
			{
				break;
			}
		}
	}
	return_code = (cmd->todo)(list->count, (char**)(list->content));
	delete_list(list);
	lily_ui.rtc = return_code;
	if (return_code == 0)
		return return_code | shell_dos_done;
	return return_code;
}